package com.shrcl.engineerprocess.domain.impl;

import com.shrcl.engineerprocess.domain.Notification;
import com.shrcl.engineerprocess.domain.NotificationStatus;
import com.shrcl.engineerprocess.domain.NotifyReceiver;
import com.shrcl.engineerprocess.domain.impl.NotifyReceiverImpl;
import com.shrcl.engineerprocess.domain.proxy.NotificationProxy;
import edu.fudan.langlab.domain.statemachine.ModelObjectLogService;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;

@Entity
@DiscriminatorValue("NOTIFICATION_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "notification")
public class NotificationImpl extends BaseModelObject implements Notification {
  public NotificationImpl() {
    super();
  }
  
  private NotificationStatus Status;
  
  public NotificationStatus getStatus() {
    return this.Status;
  }
  
  private ModelObjectLogService getModelObjectLogService() {
    return getBeanFactory().getBean(ModelObjectLogService.class);
  }
  
  private void _start() {
    
    this.init();
    Status=NotificationStatus.created;
  }
  
  public void start() {
    if(Status==null){
    	_start();
    	getModelObjectLogService().createLog(this,"Status","Start");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.NotificationEventsManager.class).fireStarted(this);					
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("allready started");
    }
  }
  
  private void _performNotify() {
    
    int _plus = ((this.notifyCount).intValue() + 1);
    this.notifyCount = Integer.valueOf(_plus);
    Date _date = new Date();
    this.notifyDate = _date;
    Status=NotificationStatus.notified;
  }
  
  public void performNotify() {
    if(Status==NotificationStatus.created||Status==NotificationStatus.notified){
    	_performNotify();
    	getModelObjectLogService().createLog(this,"Status","performNotify");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.NotificationEventsManager.class).firePerformNotify(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _confirm(final String comment) {
    
    this.comment = comment;
    Date _date = new Date();
    this.confirmDate = _date;
    Status=NotificationStatus.confirmed;
  }
  
  public void confirm(final String comment) {
    if(Status==NotificationStatus.notified){
    	_confirm(comment);
    	getModelObjectLogService().createLog(this,"Status","confirm");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.NotificationEventsManager.class).fireConfirm(this,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  public Boolean isCreated() {
    return com.shrcl.engineerprocess.domain.NotificationStatus.created==Status;
  }
  
  public Boolean isNotified() {
    return com.shrcl.engineerprocess.domain.NotificationStatus.notified==Status;
  }
  
  public Boolean isConfirmed() {
    return com.shrcl.engineerprocess.domain.NotificationStatus.confirmed==Status;
  }
  
  @JoinColumn(name = "receiver_id")
  @ManyToOne(targetEntity = NotifyReceiverImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private NotifyReceiver receiver;
  
  public NotifyReceiver getReceiver() {
    return this.receiver;
  }
  
  public Notification setReceiver(final NotifyReceiver receiver) {
    this.receiver = receiver;
    return this;			
    
  }
  
  private Date notifyDate;
  
  public Date getNotifyDate() {
    return this.notifyDate;
  }
  
  public Notification setNotifyDate(final Date notifyDate) {
    this.notifyDate = notifyDate;
    return this;			
    
  }
  
  private Date confirmDate;
  
  public Date getConfirmDate() {
    return this.confirmDate;
  }
  
  public Notification setConfirmDate(final Date confirmDate) {
    this.confirmDate = confirmDate;
    return this;			
    
  }
  
  private Integer notifyCount = Integer.valueOf(0);
  
  public Integer getNotifyCount() {
    return this.notifyCount;
  }
  
  public Notification setNotifyCount(final Integer notifyCount) {
    this.notifyCount = notifyCount;
    return this;			
    
  }
  
  private String comment;
  
  public String getComment() {
    return this.comment;
  }
  
  public Notification setComment(final String comment) {
    this.comment = comment;
    return this;			
    
  }
  
  private String notificationType;
  
  public String getNotificationType() {
    return this.notificationType;
  }
  
  public Notification setNotificationType(final String notificationType) {
    this.notificationType = notificationType;
    return this;			
    
  }
  
  public void doNotify() {
  }
  
  public void init() {
  }
  
  public Integer getImportance() {
    return Integer.valueOf(0);
  }
  
  public static Notification create(final IObjectFactory objectFactory) {
    com.shrcl.engineerprocess.domain.Notification notification = new com.shrcl.engineerprocess.domain.impl.NotificationImpl(
    );
    objectFactory.create(notification);
    return notification;			
    
  }
  
  public static Notification createNotificationImpl(final IObjectFactory objectFactory, final Procedure1<Notification> init) {
    com.shrcl.engineerprocess.domain.Notification notification = new com.shrcl.engineerprocess.domain.impl.NotificationImpl(
    );
    objectFactory.create(notification);
    init.apply(notification);
    
    return notification;			
    
  }
  
  public NotificationProxy toProxy() {
    com.shrcl.engineerprocess.domain.proxy.NotificationProxy proxy = new com.shrcl.engineerprocess.domain.proxy.NotificationProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    proxy.setStatus(this.getStatus().name());
    return proxy;
    
  }
}
